<?php

namespace App\Miya\Tools;

use App\Miya\Models\Area;
use App\Miya\Models\Keyword;
use Illuminate\Database\Eloquent\ModelNotFoundException;

class KeywordTool
{
    /**
     * 自动挑选出现频率最低的关键词
     * @return mixed
     */
    public function autoSelect($relation)
    {
        if (Keyword::count() == 0) {
            throw new ModelNotFoundException('关键词列表为空,请添加关键词再进行操作!');
        }

        $keyword = Keyword::withCount($relation)->get()->sortBy($relation . '_count')->first();
        return $keyword;
    }

    /**
     * 生成指定关键词的衍生词
     * @param Keyword $keyword
     * @param null $areas
     * @return array
     */
    public function buildDerivative(Keyword $keyword, $areas = null)
    {
        //清理之前的衍生词
        $keyword->derivatives()->delete();
        //如果未传入地区信息,兜底
        if (!$areas) {
            $areas = Area::select(['id', 'name'])->get();
        }

        //衍生关键词数据
        $derivativeData = [];

        //允许生成的衍生词类型
        $allowTypes = explode(',', config('keyword.derivative_types'));
        //原始词
        $derivativeData[] = [0, $keyword->keyword];
        //地区词
        $type1Keywords = [];
        if ($keyword->area_id) { #存在替换地区
            $areas->filter(function ($area) use ($keyword) {
                return ($area->id != $keyword->area_id) and (array_search($area->id, $keyword->ignore_areas) === false);
            })->each(function ($area) use ($keyword, &$derivativeData, &$type1Keywords) {
                $newKeyword = str_replace($keyword->area->name, $area->name, $keyword->keyword);
                $type1Keywords[] = ['keyword' => $newKeyword, 'area' => $area->id];
                $derivativeData[] = [1, $newKeyword, $area->id];
            });
        } else { #不存在替换地区
            $areas->each(function ($area) use ($keyword, &$derivativeData, &$type1Keywords) {
                $newKeyword = sprintf('%s%s', $area->name, $keyword->keyword);
                $type1Keywords[] = ['keyword' => $newKeyword, 'area' => $area->id];
                $derivativeData[] = [1, $newKeyword, $area->id];
            });
        }

        //词头衍生词
        if (array_search(2, $allowTypes) !== false) {
            if (count($keyword->prefix) > 0) {
                collect($keyword->prefix)->each(function ($prefix) use ($keyword, &$derivativeData) {
                    $derivativeData[] = [2, sprintf('%s%s', $prefix, $keyword->keyword)];
                });
            }
        }

        //地区词头衍生词
        if (array_search(5, $allowTypes) !== false) {
            if (count($keyword->prefix) > 0) {
                $type5Data = collect($keyword->prefix)->crossJoin($type1Keywords);
                collect($type5Data)->each(function ($data) use ($keyword, &$derivativeData) {
                    $derivativeData[] = [5, $data[0] . $data[1]['keyword'], $data[1]['area']];
                });
            }
        }

        //词尾衍生词
        if (array_search(3, $allowTypes) !== false) {
            if (count($keyword->suffix) > 0) {
                collect($keyword->suffix)->each(function ($suffix) use ($keyword, &$derivativeData) {
                    $derivativeData[] = [3, sprintf('%s%s', $keyword->keyword, $suffix)];
                });
            }
        }

        //地区词尾衍生词
        if (array_search(6, $allowTypes) !== false) {
            if (count($keyword->suffix) > 0) {
                $type6Data = collect($type1Keywords)->crossJoin($keyword->suffix);
                collect($type6Data)->each(function ($data) use ($keyword, &$derivativeData) {
                    $derivativeData[] = [6, $data[0]['keyword'] . $data[1], $data[0]['area']];
                });
            }
        }

        //长尾词
        if (array_search(4, $allowTypes) !== false) {
            if (count($keyword->prefix) > 0 && count($keyword->suffix) > 0) {
                $type4Data = collect($keyword->prefix)->crossJoin([$keyword->keyword], $keyword->suffix);
                collect($type4Data)->each(function ($data) use ($keyword, &$derivativeData) {
                    $derivativeData[] = [4, implode('', $data)];
                });
            }
        }

        //地区长尾词
        if (array_search(7, $allowTypes) !== false) {
            if (count($keyword->prefix) > 0 && count($keyword->suffix) > 0) {
                $type7Data = collect($keyword->prefix)->crossJoin($type1Keywords, $keyword->suffix);
                collect($type7Data)->each(function ($data) use ($keyword, &$derivativeData) {
                    $derivativeData[] = [7, $data[0] . $data[1]['keyword'] . $data[2], $data[1]['area']];
                });
            }
        }

        return collect($derivativeData)->map(function ($data) use ($keyword) {
            return ['keyword_id' => $keyword->id, 'type' => $data[0], 'keyword' => $data[1], 'area_id' => $data[2] ?? null];
        })->toArray();
    }
}
